/**
 * 图片处理
 * Author: Void rangers
 * Date: 2021.11.17
 * Version: 1.0.0
 * Description: 包含图片压缩等操作
 */

;
!function(win){
    function ImageProcess(options){
        this.default = {
            compress: {     //压缩配置 false为不压缩
                maxWidth: 1400,
                maxHeight: 1400,
                type: 'image/jpeg',
                format: 'base64',
                quality: .8
            }
        };
        this.opts = {};

        for(var i in this.default){
            let item = this.default[i];
            if(options[i]) item = Object.assign(item, options[i]);
            this.opts[i] = { ...item};
        }
        // console.log('ImageProcess options:', this.opts);
    }

    ImageProcess.prototype = {
        compress(file, opts = {}){
            if(!file || !window.FileReader) return;
            if(!this.opts.compress){
                console.warn('压缩配置已关闭(默认开启)，请设置后重试！');
                return false;
            }
            let _this = this,
                config = Object.assign({}, this.opts.compress, opts);
            // console.log('compress config:', config);
            return new Promise((resolve, reject) => {
                if(/^image/.test(file.type)){
                    const reader = new FileReader(),
                        img = new Image();
                    reader.readAsDataURL(file);
                    this.filename = file.name;
                    new Promise((res, rej) => {
                        reader.onloadend = function(){
                            img.src = this.result;
                            img.onload = res;
                        };
                    }).then(() => {
                        const { width: originWidth, height: originHeight } = img; //上传的图片的宽高
                        // console.log('origin size:', originWidth + ' * ' + originHeight);
                        if(originWidth > config.maxWidth || originHeight > config.maxHeight){
                            let proportion, targetWidth, targetHeight;
                            if(originWidth > originHeight){ //宽 >= 高
                                proportion = Number((originWidth / config.maxWidth).toFixed(4));
                            } else {    //高 > 宽
                                proportion = Number((originHeight / config.maxHeight).toFixed(4));
                            }
                            targetWidth = parseInt(originWidth / proportion);   //缩放后的宽度
                            targetHeight = parseInt(originHeight / proportion); //缩放后的高度

                            resolve(_this._createCanvas(img, targetWidth, targetHeight, config.type, config.quality, config.format));
                        } else {    //无需压缩
                            if(config.format == 'base64'){
                                resolve(file);
                            } else {
                                resolve(_this._createCanvas(img, originWidth, originHeight, config.type, config.quality, config.format));
                            }
                        }
                    });
                }
            })
        },
        _createCanvas(img, targetWidth, targetHeight, type = 'image/jpeg', quality = .8, format = 'base64'){
            // console.log('_createCanvas:', arguments);
            const canvas = document.createElement('canvas'),
                ctx = canvas.getContext('2d');
            canvas.width = targetWidth;
            canvas.height = targetHeight;
            //把图片绘制到画布
            ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
            return new Promise((resolve, reject) => {
                switch(format){
                    case 'file':
                        let base64 = canvas.toDataURL(type, quality),
                            arr = base64.split(','),
                            bstr = atob(arr[1]),
                            n = bstr.length,
                            u8arr = new Uint8Array(n);
                        
                        while(n--){
                            u8arr[n] = bstr.charCodeAt(n);
                        }
                        resolve(new File([u8arr], this.filename, { type: type}));
                        break;
                    case 'blob':
                        canvas.toBlob(blob => {
                            blob.lastModified = Date.now();
                            blob.lastModifiedDate = new Date();
                            blob.name = this.filename;
                            resolve(blob);
                        }, type, quality);
                        break;
                    case 'base64':
                    default:
                        resolve(canvas.toDataURL(type, quality));
                }
            })
        },
    }

    win.ImageProcess = ImageProcess;
}(window);